package com.fuyun.microservice.utils;

import io.netty.buffer.ByteBuf;
import org.apache.commons.lang.math.RandomUtils;
import java.nio.charset.Charset;
import java.util.Base64;
import java.util.concurrent.atomic.AtomicLong;

public class BufferUtil {

    public final static String ENCODE_CHARSET = "UTF-8";
    public final static Charset CHARSET_DEFAULT = Charset.forName(ENCODE_CHARSET);
    public final static int DWORD_LENGTH = 4;
    private final static long LIMITED = 0x7fffffffffff0000L;
    /**
     * 将ByteBuf转为json
     *
     * @param buffer
     * @return
     * @throws Exception
     */
    public static String toJSON(ByteBuf buffer) throws Exception {
        byte[] req = new byte[buffer.readableBytes()];
        buffer.readBytes(req);
        String jsonStr = new String(req, ENCODE_CHARSET);
        return jsonStr;
    }

    /**
     * 明文转base64
     *
     * @param text
     * @return
     */
    public static byte[] toBase64(String text) {
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encode(text.getBytes(CHARSET_DEFAULT));
    }

    /**
     * 返回一个定长的数组
     *
     * @param text
     * @param length
     * @return
     */
    public static byte[] toFixedBytes(String text, int length) {
        byte[] fixBytes = new byte[length];
        byte[] textBytes = text.getBytes(BufferUtil.CHARSET_DEFAULT);
        System.arraycopy(textBytes, 0, fixBytes, 0, textBytes.length > length ? length : textBytes.length);
        return fixBytes;
    }

    /**
     * base64转明文
     *
     * @param buffer
     * @return
     */
    public static String fromBase64(byte[] buffer) {
        Base64.Decoder decoder = Base64.getDecoder();
        return new String(decoder.decode(buffer), CHARSET_DEFAULT);
    }


    /**
     * 去除异常填充
     *
     * @param buffer
     * @return
     */
    public static String readStringExcludeEmpty(byte[] buffer) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < buffer.length; i++) {
            byte v = buffer[i];
            if (v > 0) {
                sb.append((char) v);
            } else {
                break;
            }
        }

        return sb.toString();
    }


    private final static AtomicLong sequenceIdAtomic = new AtomicLong(Math.abs(RandomUtils.nextInt()));
    public static long getSequenceNo() {
        return getNextAtomicValue(LIMITED);
    }

    /**
     * 实现AtomicLong对象的线程安全循环自增
     *
     * @param limited   最大值
     */
    public static long getNextAtomicValue(long limited) {
        long ret = sequenceIdAtomic.getAndIncrement();

        if (ret > limited) { // Long.MAX_VALUE - 0xfff
            synchronized (sequenceIdAtomic) {
                //双重判断，只能有一个线程更新值
                if (sequenceIdAtomic.get() > limited) {
                    sequenceIdAtomic.set(0);
                    return 0;
                } else {
                    return sequenceIdAtomic.getAndIncrement();
                }
            }
        } else {
            return ret;
        }
    }

    public static byte[] toByteArraySafe(ByteBuf byteBuf) {
        if (byteBuf.hasArray()) {
            return byteBuf.array();
        }

        byte[] bytes = new  byte[byteBuf.readableBytes()];
        byteBuf.getBytes(byteBuf.readerIndex(),bytes);
        return bytes;
    }
}
